home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Megahits 5
/
Megahits 5 (1994)(GTI - Rhein-Main-Soft)(DE)(Disc 2 of 2)[!].iso
/
archive
/
conv
/
wasp202b.lha
/
wasp
/
src
/
operations.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-12-31
|
7KB
|
343 lines
/* wasp - Copyright 1991 by Steven Reiz
* see COPYING and wasp.c for further info
* operations.c, 4/12/90 - 23/6/91, 16/11/91,
* 8/12/91, 27/12/91 - 31/12/91
*/
static char *sourcefile=__FILE__;
#include "wasp.h"
void
scalex(int t, int n)
{
NON_REG u_long newxsz;
REG u_short **newrgb;
REG long x, y, xtot, newx;
if (t==n || t<=0 || n<=0)
return;
init_counter(0, (int)xsz, 20, "x scaling %d/%d", t, n);
newxsz=xsz*t/n;
newrgb=Malloc(ysz*sizeof(u_short *));
for (y=0; y<ysz; ++y)
newrgb[y]=Calloc(newxsz*sizeof(u_short));
xtot=0; newx=0;
for (x=0; x<xsz; ++x) {
counter();
xtot+=t;
while (xtot>=n) {
xtot-=n;
y=ysz-1;
do {
newrgb[y][newx]=rgb[y][x];
} while (--y>=0);
++newx;
}
}
for (y=0; y<ysz; ++y)
free(rgb[y]);
free(rgb);
rgb=newrgb;
xsz=newxsz;
erase_counter("x scaling done; %ld x %ld", xsz, ysz);
}
void
scaley(int t, int n)
{
NON_REG u_long newysz;
NON_REG u_short **newrgb;
NON_REG short y, ytot, newy;
REG u_short *p, *q;
REG short i;
if (t==n || t<=0 || n<=0)
return;
init_counter(0, (int)ysz, 20, "y scaling %d/%d", t, n);
newysz=ysz*t/n;
newrgb=Malloc(newysz*sizeof(u_short *));
ytot=0; newy=0;
for (y=0; y<ysz; ++y) {
counter();
ytot+=t;
while (ytot>=n) {
ytot-=n;
newrgb[newy]=Calloc(xsz*sizeof(u_short));
p=newrgb[newy];
q=rgb[y];
i=xsz-1;
do {
*p++ = *q++;
} while (--i>=0);
++newy;
}
free(rgb[y]);
}
free(rgb);
rgb=newrgb;
ysz=newysz;
erase_counter("y scaling done; %ld x %ld", xsz, ysz);
}
struct fac_t {
int t, n;
} facs[]={
4, 1,
3, 1,
2, 1,
1, 1,
1, 2,
1, 3,
2, 3,
1, 4,
3, 4,
1, 5,
4, 5,
1, 6,
0, 0
};
void
scalef(int yflag, float factor)
{
int t, n;
int i, besti;
float error, besterror, tf;
besterror=1000.0;
for (i=0; facs[i].n; ++i) {
tf=(float)facs[i].t/(float)facs[i].n;
if (tf<=factor) {
error=factor-tf;
if (error<besterror) {
besti=i;
besterror=error;
}
}
}
t=facs[besti].t;
n=facs[besti].n;
if (t==4 && n==1)
t=(int)(factor+0.5);
else if (t==1 && n==6)
n=(int)(1/factor+0.5);
if (yflag)
scaley(t, n);
else
scalex(t, n);
}
void
do_clipping(int minx, int maxx, int miny, int maxy)
{
int newxsz, newysz;
u_short **newrgb;
short x, y;
u_short *p, *q;
printe("clipping; [0..%ld x 0..%ld] -> [%d..%d x %d..%d]\n",
xsz-1, ysz-1, minx, maxx, miny, maxy);
if (minx<0 || miny<0 || maxx>=xsz || maxy>=ysz || maxx<minx || maxy<miny)
error0(E0_FATAL, E1_OPERATION, E2_OPTION, E3_CLIP_REGION);
newxsz=maxx-minx+1;
newysz=maxy-miny+1;
for (y=0; y<miny; ++y)
free(rgb[y]);
for (y=maxy+1; y<ysz; ++y)
free(rgb[y]);
newrgb=Malloc(newysz*sizeof(u_short *));
init_counter(0, (int)newysz, 20, "clipping");
for (y=0; y<newysz; ++y) {
counter();
newrgb[y]=Calloc(newxsz*sizeof(u_short));
p=newrgb[y];
q=rgb[y+miny]+minx;
x=newxsz-1;
do {
*p++ = *q++;
} while (--x>=0);
free(rgb[y+miny]);
}
free(rgb);
rgb=newrgb;
xsz=newxsz;
ysz=newysz;
erase_counter("clipping done; %ld x %ld", xsz, ysz);
}
void
do_enlarge(int newxsz, int newysz)
{
u_short **newrgb;
short x, y, x0, y0;
u_short *p, *q;
printe("enlarging; [%ld x %ld] -> [%d x %d]\n", xsz, ysz, newxsz, newysz);
if (newxsz<xsz || newysz<ysz)
error0(E0_FATAL, E1_OPERATION, E2_OPTION, E3_ENLARGE_SIZE);
newrgb=Malloc(newysz*sizeof(u_short *));
x0=(newxsz-xsz)/2;
y0=(newysz-ysz)/2;
init_counter(0, (int)newysz, 20, "enlarging");
for (y=0; y<newysz; ++y) {
counter();
if (newxsz==xsz && y>=y0 && y<y0+ysz)
newrgb[y]=rgb[y-y0];
else
newrgb[y]=Calloc(newxsz*sizeof(u_short));
if (newxsz!=xsz && y>=y0 && y<y0+ysz) {
p=newrgb[y]+x0;
q=rgb[y-y0];
x=xsz-1;
do {
*p++ = *q++;
} while (--x>=0);
free(rgb[y-y0]);
}
}
free(rgb);
rgb=newrgb;
xsz=newxsz;
ysz=newysz;
erase_counter("enlarging done; %ld x %ld", xsz, ysz);
}
void
xaverage(void)
{
NON_REG int y;
REG short x, *p, *q;
NON_REG u_short *oldrgby;
REG long c1, c2, mask1, mask2;
NON_REG long newxsz;
init_counter(0, (int)ysz, 20, "xaveraging");
newxsz=xsz/2;
mask1=0xeef;
mask2=0x110;
for (y=0; y<ysz; ++y) {
counter();
oldrgby=rgb[y];
p=(short *)oldrgby;
rgb[y]=Calloc(newxsz*sizeof(u_short));
q=(short *)rgb[y];
x=newxsz-1;
do {
c1= *p++;
c2= *p++;
*q++ =(((c1&mask1)+(c2&mask1))>>1)+(c1&c2&mask2);
} while (--x>=0);
free(oldrgby);
}
xsz=newxsz;
erase_counter("xaverage done; %ld x %ld", xsz, ysz);
}
void
xmirror(void)
{
u_short *line;
short y, x;
u_short *p, *q;
init_counter(0, (int)ysz, 20, "xmirroring");
line=Malloc(xsz*sizeof(u_short));
for (y=0; y<ysz; ++y) {
counter();
x=xsz-1;
p=line;
q=rgb[y]+xsz;
do {
*p++ = *--q;
} while (--x>=0);
p=rgb[y];
rgb[y]=line;
line=p;
}
erase_counter("xmirror done");
free(line);
}
void
ymirror(void)
{
short i, j;
u_short *p;
i=0;
j=ysz-1;
while (i<j) {
p=rgb[i];
rgb[i]=rgb[j];
rgb[j]=p;
++i;
--j;
}
printe("ymirror done\n");
}
void
transpose(void)
{
u_short **newrgb;
short x, y;
u_short *p;
long t;
init_counter(0, (int)ysz, 10, "transposing");
newrgb=Malloc(xsz*sizeof(u_short *));
for (y=0; y<xsz; ++y)
newrgb[y]=Calloc(ysz*sizeof(u_short));
for (y=0; y<ysz; ++y) {
counter();
x=xsz-1;
p=rgb[y]+xsz;
do {
newrgb[x][y]= *--p;
} while (--x>=0);
free(rgb[y]);
}
free(rgb);
rgb=newrgb;
t=xsz;
xsz=ysz;
ysz=t;
erase_counter("transpose done; %ld x %ld", xsz, ysz);
}
void
testpat(int testx, int testy)
{
long x, y, cx, cy;
u_short clr;
xsz=testx;
ysz=testy;
printe("TESTPAT input; %ld x %ld\n", xsz, ysz);
rgb=Malloc(ysz*sizeof(u_short *));
init_counter(0, (int)ysz, 20, "creating test pattern");
for (y=0; y<ysz; ++y)
rgb[y]=Calloc(xsz*sizeof(u_short));
for (y=0; y<ysz; ++y) {
counter();
cy=(64L*y)/ysz;
clr=((cy&3)<<6)|((cy&60)>>2);
for (x=0; x<xsz; ++x) {
cx=(64L*x)/xsz;
rgb[y][x]=clr|((cx&60)<<6)|((cx&3)<<4);
}
}
erase_counter(NULL);
}